package edu.upb.acs.jobsmaps.activity.voiceRecognition;

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.widget.EditText;
import android.widget.Spinner;
import edu.upb.acs.jobsmaps.R;
import edu.upb.acs.jobsmaps.entity.Company;
import edu.upb.acs.jobsmaps.voice.DropDownComplete;

import java.util.ArrayList;

/**
 * Created by dani on 6/28/2014.
 */
public class VoiceRecognitionListenerCompany  implements RecognitionListener {
	private static final String TAG = "VoiceRecognitionListenerCompany";

	private SpeechRecognizer sr;
	private Intent intent;
	private TextToSpeech tts;
	private AudioManager amAudioManager;
	private int fields = 0;
	private Activity activity;

	public VoiceRecognitionListenerCompany(SpeechRecognizer sr, Intent intent, TextToSpeech tts, AudioManager amAudioManager, Activity activity) {
		this.sr = sr;
		this.intent = intent;
		this.tts = tts;
		this.amAudioManager = amAudioManager;
		this.activity = activity;

		//number of fields to be completed
		fields = 0;
	}

	public void onReadyForSpeech(Bundle params) {
		Log.d(TAG, "onReadyForSpeech");
	}

	public void onBeginningOfSpeech() {
		Log.d(TAG, "onBeginningOfSpeech");
	}

	public void onRmsChanged(float ramsB) {
//            Log.d(TAG, "onRmsChanged");
	}

	public void onBufferReceived(byte[] buffer) {
		Log.d(TAG, "onBufferReceived");
	}

	public void onEndOfSpeech() {
		Log.d(TAG, "onEndofSpeech");
	}

	public void onError(int error) {
		Log.d(TAG, "error " + error);

		switch (error) {
			case SpeechRecognizer.ERROR_NO_MATCH:
				speak("No match, try again");
				sr.startListening(intent);
				break;
			case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
				speak("No match, try again");
				sr.startListening(intent);
				break;
			case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
			case SpeechRecognizer.ERROR_NETWORK:
			case SpeechRecognizer.ERROR_SERVER:
			case SpeechRecognizer.ERROR_CLIENT:
			case SpeechRecognizer.ERROR_AUDIO:
				speak("No match, try again");
				sr.startListening(intent);
				break;
			case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
				speak("The speak functionality is busy. Try again");
				sr.startListening(intent);
				break;
			case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
				speak("No permisions to run this");
				break;
			default:
				Log.d(TAG, "Error unknown");
		}
	}

	public void speak(String input) {
		amAudioManager.setMicrophoneMute(true);
		tts.speak(input, TextToSpeech.QUEUE_FLUSH, null);
		waitForSpeaker();
	}

	public void onResults(Bundle results) {
		String str = new String();
		Log.d(TAG, "onResults " + results);
		ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
		final Company company = new Company();

		//for (int i = 0; i < data.size(); i++) {
		Log.d(TAG, "result " + data.get(0));
		str += data.get(0);

		String text = data.get(0);

		boolean errorFound = false;

		switch (fields) {
			case 0:
				final EditText nameField = (EditText) activity.findViewById(R.id.addCompanyName);
				nameField.setText(text);
				company.setName(text);
				speak("Description");
				fields++;
				break;
			case 1:
				final EditText descField = (EditText) activity.findViewById(R.id.addCompanyDescription);
				descField.setText(text);
				company.setDescription(text);
				speak("Profile");
				fields++;
				break;
			case 2:
				Spinner spinner = (Spinner) activity.findViewById(R.id.addCompanyProfile);
				Integer indexValue = DropDownComplete.setDropDownValue(spinner, data);
				if (indexValue != null){
					spinner.setSelection(indexValue);
					company.setProfile(spinner.getItemAtPosition(indexValue).toString());
				} else {
					speak("No match, try again");
					sr.startListening(intent);
					errorFound = true;
					break;
				}
				speak("Latitude");
				fields++;
				break;
			case 3:
				final EditText latitude = (EditText) activity.findViewById(R.id.addCompanyLatitude);
				try {
					latitude.setText(text);
					company.setLatitude(Double.valueOf(text));
				} catch (NumberFormatException e) {
					speak("No match, try again");
					sr.startListening(intent);
					errorFound = true;
					break;
				}
				speak("Longitude");
				fields++;
				break;
			case 4:
				final EditText longitude = (EditText) activity.findViewById(R.id.addCompanyLongitude);
				try {
					longitude.setText(text);
					company.setLongitude(Double.valueOf(text));
				} catch (NumberFormatException e) {
					speak("No match, try again");
					sr.startListening(intent);
					errorFound = true;

					break;
				}
				speak("Link");
				fields++;
				break;
			case 5:
				final EditText link = (EditText) activity.findViewById(R.id.addCompanyUrlVoice);
				link.setText(text);
				company.setCompanyUrl(text);
				fields++;
				break;
			default:
				Log.d(TAG, "fields =  " + fields);
		}

		if (!errorFound) {
			if (fields < 6) {
				sr.startListening(intent);
			} else {
				tts.speak("Done", TextToSpeech.QUEUE_FLUSH, null);
			}
		}
	}


	public void waitForSpeaker() {
		Log.d(TAG, "waiting for tts to finish");
		do {
			//TODO
		} while (tts.isSpeaking());
		Log.d(TAG, "done waiting");

		amAudioManager.setMicrophoneMute(false);
	}

	public void onPartialResults(Bundle partialResults) {
		Log.d(TAG, "onPartialResults");
	}

	public void onEvent(int eventType, Bundle params) {
		Log.d(TAG, "onEvent " + eventType);
	}

}
